<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>随机生成div</title>
<style>
html{
height: 100%;
}
body{
width:100%;
margin:0;
padding:0;
height:100%;
}
div.wrap{
height:100%;
position: relative;
overflow: hidden;
margin:0;
padding:0;

}

div:not(.wrap){
border-radius: 50%;
/*-webkit-animation:tanslateAni 5000ms infinite linear alternate;*/
/*transition: all 10000ms linear;*/
}
div:nth-of-type(2){
-webkit-animation-delay:2000ms;
}
div:nth-of-type(3){
-webkit-animation-delay:4000ms;
}
div:nth-of-type(4){
-webkit-animation-delay:-1000ms;
}

@-webkit-keyframes tanslateAni{
0% {-webkit-transform:rotate(10deg) translate3d(0px,0px,0)}
35% {-webkit-transform:rotate(0deg) translate3d(20px,0px,0)}
70% {-webkit-transform:rotate(-10deg) translate3d(0px,0px,0)}
100% {-webkit-transform:rotate(0deg) translate3d(-20px,0px,0)}
}
</style>
</head>
<body>
<div class="wrap" id='parent'></div>
<script>
	var elWidth=110;
	var containerWidth;
	var color=['red','green','blue','black','yellow'];//随机的颜色
	var ballNum=20;
	//var pageHeight=window.screen.height;
	var pageHeight=document.body.clientHeight;
	//var pageWidth=window.screen.width;
	var pageWidth=document.body.clientWidth;
	containerWidth=pageWidth;
	var sizeRange=60;
	var balls=[];

	window.onload=function(){
		
	    createBalls(elWidth+sizeRange,pageWidth,pageHeight,ballNum);
	    setInterval(function(){ballHit(balls,pageWidth,pageHeight)},30)
	}
	//生成虚拟网格
	function createTable(ballWidth,pageWidth,pageHeight){
		
	    var col=Math.floor(pageWidth/ballWidth);
	    var marginH=pageWidth%ballWidth;
	    var marginV=pageHeight%ballWidth;
	    var row=Math.floor(pageHeight/ballWidth);
	    var total=col*row;
	    var ballMap=[];
	    for(var i=0;i<total;i++){//网格map存入一维数组
	        //top、left值有较大偏差原因：/、%运算为小数，与Java不同
	        ballMap[i]={left:marginH/2+Math.floor(i%col)*ballWidth,top:marginV/2+Math.floor(i/col)*ballWidth}
	    }
	    return ballMap;
	}
//生成小球
	var spaceIndex=10;
	function createBalls(ballWidth,pageWidth,pageHeight,ballNum){
	    var ballMap=createTable(ballWidth,pageWidth,pageHeight);
	    console.log("ballMap.length %d",ballMap.length);
	    var range=ballMap.length
	    if(ballNum>=range-spaceIndex){
	        ballNum=range-spaceIndex;
	    }
	    console.log("ballNum %d, range %d",ballNum,range);
	    var ballsData=[];
	    var ballIndex;

	    ballIndex=getRandom(0,range,ballNum);

	    for(var i=0;i<ballIndex.length;i++){
	        ballsData[i]=ballMap[ballIndex[i]];
	    }
	    renderBalls(ballsData,ballNum);
	}
	//渲染小球
	function renderBalls(ballData,ballNum){
	    for(var i=0;i<ballNum;i++){
	        var divBall=createEl('div')
	        //（待改进），用面向对象方式改进
	        balls.push({el:divBall,left:ballData[i].left,top:ballData[i].top,
	            vx:Math.random()*6-3,vy:Math.random()*6-3,
	            raduis:parseInt(divBall.style.width)/2});
	    }
	    for(var j=0;j<ballNum;j++){
	        balls[j].el.style.left=balls[j].left+'px';
	        balls[j].el.style.top=balls[j].top+'px';
	    }
	}

	//随机数去重
	function noRepeat(arr,newNum,range){
	        var isRepeat=false;
	        for(var i=0;i<arr.length;i++){
	            if(newNum==arr[i]){
	                isRepeat=true;
	                break;
	            }
	        }
	        if(isRepeat){
	            newNum=Math.floor(Math.random()*range);
	            noRepeat(arr,newNum,range);
	        }else{
	            return newNum;
	        }
	}

	//随机数去重工具函数2
	function getRandom(min,max,n){
	    if (n > (max - min + 1) || max < min) {
	        return null;
	    }
	    var result = [];
	    var count = 0;
	    while(count < n) {
	        var num =Math.floor(Math.random() * (max - min)) + min;
	        var flag = true;
	        for (var j = 0; j < n; j++) {
	            if(num == result[j]){
	                flag = false;
	                break;
	            }
	        }
	        if(flag){
	            result[count] = num;
	            count++;
	        }
	    }
	    return result;
	}

	//随机生成一个dom元素
	function createEl(el,text){
	    var elment=document.createElement(el);
	    document.getElementById('parent').appendChild(elment);
	    // console.log(element);
	    var len=Math.ceil(Math.random()*sizeRange);
	    elment.style.width=len+elWidth+'px';
	    elment.style.height=len+elWidth+'px';
	    elment.style.backgroundColor=color[Math.floor(Math.random()*5)];
	    elment.style.position='absolute';
	    elment.innerHTML=text||"";
	    return elment;
	}

	function moveBall(balls){
	    for(var i=0;i<balls.length;i++){
	        balls[i].left+=balls[i].vx;
	        balls[i].top+=balls[i].vy;
	        balls[i].el.style.left=balls[i].left+'px';
	        balls[i].el.style.top=balls[i].top+'px';
	    }
	}

	var spring= 1;//球与球之间弹性系数
	var bounce=-1;//球与边缘之间弹性系数
	function ballHit(balls,pageWidth,pageHeight){
	    //检测边缘
	    for(var i=0;i<balls.length;i++){
	        if(balls[i].left<=0||balls[i].left>=pageWidth-2*balls[i].raduis){
	            balls[i].vx*=bounce;
	        }
	        if(balls[i].top<=0||balls[i].top>=pageHeight-2*balls[i].raduis){
	            balls[i].vy*=bounce;
	        }
	    }
	    //检测小球与小球
	    for (i=0;i<balls.length;i++) {
	        var ball1=balls[i];
	        ball1.x=ball1.left+ball1.raduis;
	        ball1.y=ball1.top+ball1.raduis;
	        for (j=i+1;j<balls.length;j++) {
	            var ball2=balls[j];
	            ball2.x=ball2.left+ball2.raduis;
	            ball2.y=ball2.top+ball2.raduis;
	            dx=ball2.x-ball1.x;
	            dy=ball2.y-ball1.y;
	            var dist=Math.sqrt(dx*dx + dy*dy);
	            var misDist=ball1.raduis+ball2.raduis;
	            if(dist < misDist) {
	                var angle=Math.atan2(dy,dx);
	                tx=ball1.x+Math.cos(angle) * misDist;
	                ty=ball1.y+Math.sin(angle) * misDist;
	                ax=(tx-ball2.x) * spring;
	                ay=(ty-ball2.y) * spring;
	                ball1.vx-=ax;
	                ball1.vy-=ay;
	                ball2.vx+=ax;
	                ball2.vy+=ay;
	            }
	        }
	    }
	    moveBall(balls);
	}

</script>
</body>
</html>